import json
import os
import shutil
import sys
import time
import traceback

from flask import Flask
from flask import request, jsonify

import logging
from logging.handlers import TimedRotatingFileHandler

from apps.auto_match import UGM, transform
from apps.downloadApartments import download_ApartmentData, downloadFile_FromAli

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(BASE_DIR)
CACHE_DIR = os.path.join(BASE_DIR, "cache")

app = Flask(__name__)


# class Logger(object):
#     # 日志级别关系映射
#     level_relations = {
#         'debug': logging.DEBUG,
#         'info': logging.INFO,
#         'warning': logging.WARNING,
#         'error': logging.ERROR,
#         'critical': logging.CRITICAL
#     }
#
#     def __init__(self,
#                  filename,
#                  level='info',
#                  when='D',
#                  back_count=3,
#                  fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
#         f_dir, f_name = os.path.split(filename)
#         os.makedirs(f_dir, exist_ok=True)  # 当前目录新建log文件夹
#         self.logger = logging.getLogger(filename)
#         format_str = logging.Formatter(fmt)  # 设置日志格式
#         self.logger.setLevel(self.level_relations.get(level))  # 设置日志级别
#         sh = logging.StreamHandler()  # 往屏幕上输出
#         sh.setFormatter(format_str)  # 设置屏幕上显示的格式
#         th = handlers.TimedRotatingFileHandler(filename=filename, when=when, backupCount=back_count,
#                                                encoding='utf-8')  # 往文件里写入指定间隔时间自动生成文件的Handler
#         # 实例化TimedRotatingFileHandler
#         # interval是时间间隔，backupCount是备份文件的个数，如果超过这个个数，就会自动删除，when是间隔的时间单位，单位有以下几种：
#         # S 秒
#         # M 分
#         # H 小时
#         # D 天
#         # 'W0'-'W6' 每星期（interval=0时代表星期一：W0）
#         # midnight 每天凌晨
#         th.setFormatter(format_str)  # 设置文件里写入的格式
#         self.logger.addHandler(sh)  # 把对象加到logger里
#         self.logger.addHandler(th)

def logger_print(string):
    print(string)


def check_cache():
    """
    缓存项目10个，超出10则删除修改时间最早的项目文件夹
    :return:
    """
    caches = []
    for i in os.listdir(CACHE_DIR):
        caches.append(os.path.join(CACHE_DIR, i))
    if len(caches) < 10:
        return

    mTime = [os.path.getmtime(i) for i in caches]
    minTime = min(mTime)
    for i in range(len(mTime)):
        if mTime[i] == minTime:
            # os.removedirs(caches[i])
            shutil.rmtree(caches[i], ignore_errors=True)
            return


def drawing_compare(ugm_name, stageId):
    """
    比较当前户型图纸和项目中已有图纸
    :param ugm_name: str 当前户型的图纸的id
    :param stageId: str 项目id
    :return: 项目中有与之匹配图纸，则返回项目中已有的图纸和平移坐标 无匹配图纸，则将当前图纸移进项目缓存
    """
    res = {"statusCode": "200", "message": "success", "ugmName": "", "x": 0, "y": 0}
    stage_dir = os.path.join(CACHE_DIR, stageId)
    check_cache()

    # 下载项目文件
    if not os.path.exists(stage_dir):
        os.makedirs(os.path.join(CACHE_DIR, stageId))
        try:
            download_ApartmentData(stageId, os.path.join(CACHE_DIR, stageId))
        except:
            res["statusCode"] = 401
            res["message"] = "download ApartmentData failed"
            return res

    # 下载户型文件
    try:
        downloadFile_FromAli(os.path.join("ugmJson/", ugm_name), ugm_name)
    except:
        res["statusCode"] = 401
        res["message"] = "download ugm failed"
        return res
    apartMent_ugm = []
    for i in os.listdir(stage_dir):
        apartMent_ugm.append(os.path.join(stage_dir, i))

    # 项目文件为空
    if not apartMent_ugm:
        shutil.move(ugm_name, stage_dir)
        res["ugmName"] = ugm_name
        res["message"] = "no apartment data"
        res["x"] = 0
        res["y"] = 0
        return res

    t_ugm = UGM(ugm_name)
    cre_list, translate_list, s_ugm_list = [], [], []
    for i in apartMent_ugm:
        s_ugm = UGM(i)
        if s_ugm.roomNum != t_ugm.roomNum:
            continue
        cre, translate = transform(t_ugm, s_ugm)
        cre_list.append(cre)
        translate_list.append(translate)
        s_ugm_list.append(s_ugm)

    # 不存在匹配户型
    if len(cre_list) == 0 or max(cre_list) < 0.96:
        logger_print("s_ugmName : {} t_ugmName : {}".format("NO MATCH", t_ugm.name))
        shutil.move(t_ugm.name, stage_dir)
        res["ugmName"] = t_ugm.name
        res["x"] = 0
        res["y"] = 0
        return res

    # 存在匹配户型
    index = cre_list.index(max(cre_list))
    os.remove(t_ugm.name)
    s_ugm = s_ugm_list[index]
    logger_print("s_ugmName : {} t_ugmName : {}".format(s_ugm.name, t_ugm.name))
    res["ugmName"] = s_ugm.name
    res["x"] = translate_list[index].x
    res["y"] = translate_list[index].y
    return res



def delete_cache(ugmId, stageId):
    """
    删除stageId项目中，前缀为ugmId的图纸
    :param ugmId: str 当前户型的图纸的id
    :param stageId: str 项目id
    :return:
    """
    res = {"statusCode": 200, "message": "success", "deletedUgmIds": []}
    deletedUgmIds = []
    stage_dir = os.path.join(CACHE_DIR, stageId)
    if os.path.exists(stage_dir):
        for i in os.listdir(stage_dir):
            if ugmId in i:
                os.remove(os.path.join(stage_dir, i))
                deletedUgmIds.append(i)
    res["deletedUgmIds"] = deletedUgmIds
    return res


@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"


@app.route("/drawing_compare", methods=["POST"])
def drawing_compare_view():
    # logger = Logger('./logs/app.log', 'info', 'S', 5).logger
    logger_print("********* start drawing compare ********")
    data = str(request.get_data(), "utf8")
    data = json.loads(data)
    start = time.time()
    try:
        logger_print("ugmName: {}, stageId: {}".format(data["ugmName"], data["stageId"]))
        res = drawing_compare(data["ugmName"], data["stageId"])
    except Exception as e:
        logger_print(traceback.format_exc())
        logger_print("ugmName : {}, stageId : {}".format(data["ugmName"], data["stageId"]))
        res = {"statusCode": "501", "message": e.__repr__(), "ugmName": "", "x": 0, "y": 0}
        print(e)
    cost = "{}s".format(round(time.time() - start, 2))
    ret = {**res, "cost": cost}
    logger_print(json.dumps(ret))
    logger_print("********* drawing compare finished ********")
    return jsonify(ret)


@app.route("/delete_cache", methods=["POST"])
def delete_cache_view():
    # logger = Logger('./logs/app.log', 'info', 'S', 5).logger
    logger_print("********* start delete cache ********")
    data = str(request.get_data(), "utf8")
    data = json.loads(data)
    start = time.time()
    try:
        logger_print("ugmId: {}, stageId: {}".format(data["ugmId"], data["stageId"]))
        res = delete_cache(data["ugmId"], data["stageId"])
    except Exception as e:
        logger_print(traceback.format_exc())
        logger_print("ugmId: {}, stageId: {}".format(data["ugmId"], data["stageId"]))
        res = {"statusCode": "501", "message": e.__repr__()}
        print(e)
    cost = "{}s".format(round(time.time() - start, 2))
    ret = {**res, "cost": cost}
    logger_print(json.dumps(ret))
    logger_print("********* delete cache finished ********")
    return jsonify(ret)


if __name__ == '__main__':
    # t_path = r"test/f1a4a5a8-73da-469f-a784-632bda9691e4_3 (2).json"
    # s_path = r"test/f1a4a5a8-73da-469f-a784-632bda9691e4_3.json"
    # t_ugm = UGM(t_path)
    # s_ugm = UGM(s_path)
    # cre, translate = transform(s_ugm, t_ugm)
    # print(cre)

    app.debug = True
    formatter = logging.Formatter(
        "[%(asctime)s][%(filename)s:%(lineno)d][%(levelname)s][%(thread)d] - %(message)s")
    handler = TimedRotatingFileHandler(
        "flask.log", when="D", interval=1, backupCount=15,
        encoding="UTF-8", delay=False, utc=True)
    app.logger.addHandler(handler)
    handler.setFormatter(formatter)
    app.run(host='0.0.0.0', port=5000, debug=True)

    # download_ApartmentData("stage1", os.path.join(CACHE_DIR, "stage1"))
    # downloadFile_FromAli(os.path.join("ugmJson/", "fbd6ab45-d328-4070-b2bd-bad230e8a742_4.json"), "fbd6ab45-d328-4070-b2bd-bad230e8a742_4.json")
    # download_ugm("fbd6ab45-d328-4070-b2bd-bad230e8a742_4.json")
    # ugmName = r"户型拆分1-6/de64657b-bd40-4e30-be4d-7f641fa734dc_1.json"
    # t_ugm = UGM("5e56c85e-5be8-4500-9232-797a3c7b0a87_1.json")
    #
    # s_ugm = UGM("4afdf60f-3196-4c9c-8a0e-a4e7ea76289b_1.json")
    # a = transform(t_ugm, s_ugm)
    # print(a)
    # v = 0
